home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
011
/
assywind.arc
/
WINDO.INC
next >
Wrap
Text File
|
1986-07-03
|
27KB
|
500 lines
{ ===================================================================== }
{ WINDO - Windowing routines for Turbo PASCAL }
{ }
{ Author: Michael Burton }
{ 15540 Boot Hill Rd. }
{ Hayden Lake, ID 83835 }
{ (208) 772-9347 (after 1800 PST) }
{ Revision: 2.2 }
{ Date: 02 July 1986 }
{ }
{ Execute the WINTUTOR program for an explanation of use. }
{ }
{ This is a 'Shareware' program. If you find it to be of significant }
{ use to you, a $10 donation to the above address would be greatly }
{ appreciated. This would also place you on our mailing list to keep }
{ you informed of upgrades to Windo and of new programs. }
{ }
{ Modifications: }
{ DATE Rev Description }
{ 04 Mar 86 2.1 Make the heap available check properly }
{ 02 Jul 86 2.2 Get proper string length in GETDISP and DISPALL }
{ 03 Jul 86 2.3 Change Set_Cursor to properly handle monochrome }
{ ===================================================================== }
type
windimtype = record
colb,rowb,cole,rowe,attrib,bordr,lastx,lasty : byte;
end;
charptr = ^char;
winstr = string[80];
brdtype = record
ul,ur,ll,lr,hz,vtl,vtr: char;
end;
const maxwin = 30; { Total number of windows on screen at any time }
noneb = 0; { No border }
singleb = 1; { Single border }
doubleb = 2; { Double border }
mixedb = 3; { Mixed border }
solidb = 4; { Solid border }
dimondb = 5; { Diamond border }
circleb = 6; { Circles border }
lhatchb = 7; { light hatch border }
mhatchb = 8; { medium hatch border }
dhatchb = 9; { dense hatch border }
brd: array[1..9] of brdtype = (
(ul:'┌';ur:'┐';ll:'└';lr:'┘';hz:'─';vtl:'│';vtr:'│'), { single }
(ul:'╔';ur:'╗';ll:'╚';lr:'╝';hz:'═';vtl:'║';vtr:'║'), { double }
(ul:'╒';ur:'╕';ll:'╘';lr:'╛';hz:'═';vtl:'│';vtr:'│'), { mixed }
(ul:'█';ur:'█';ll:'█';lr:'█';hz:'█';vtl:'▌';vtr:'▐'), { solid }
(ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '), { diamond}
(ul:' ';ur:' ';ll:' ';lr:' ';hz:' ';vtl:' ';vtr:' '), { circle }
(ul:'░';ur:'░';ll:'░';lr:'░';hz:'░';vtl:'░';vtr:'░'), { lhatch }
(ul:'▒';ur:'▒';ll:'▒';lr:'▒';hz:'▒';vtl:'▒';vtr:'▒'), { mhatch }
(ul:'▓';ur:'▓';ll:'▓';lr:'▓';hz:'▓';vtl:'▓';vtr:'▓')); { dhatch }
var
wndo : Array [0..maxwin] of windimtype; { window attributes }
wndoptr : Array [1..maxwin] of charptr; { pointer to window on heap }
tmpptr : charptr; { temporary pointer }
l_i : byte; { level index }
wndostr : winstr; { string for building wndos }
{ ===================================================================== }
{ GETDISP - Get an array of characters from the CRT display and store }
{ them in tostrng. }
{ The row and column inputs are relative to zero and are }
{ also relative to the entire screen, not any open window. }
{ }
{ Inputs: }
{ colb : byte; Starting column (0 - 79) }
{ rowb : byte; Starting row (0 - 24) }
{ len : byte; length of array }
{ tostrng : charptr; Pointer to character storage }
{ ===================================================================== }
Procedure GetDisp(colb,rowb,len : byte; tostrng : charptr);
Begin
Inline(
$1E/ { PUSH DS }
$8A/$86/rowb/ { MOV AL,rowb[BP] }
$B3/$50/ { MOV BL,80 }
$F6/$E3/ { MUL BL }
$2B/$DB/ { SUB BX,BX }
$8A/$9E/colb/ { MOV BL,colb[BP] }
$03/$C3/ { ADD AX,BX }
$03/$C0/ { ADD AX,AX }
$8B/$F8/ { MOV DI,AX }
$C4/$B6/tostrng/ { LES SI,tostrng[BP] }
$8B/$8E/len/ { MOV CX,len[BP] }
$03/$C9/ { ADD CX,CX }
$2B/$C0/ { ADD AX,AX }
$8E/$D8/ { MOV DS,AX }
$A0/$49/$04/ { MOV AL,DS:[0449H] }
$22/$C9/ { AND CL,CL }
$74/$32/ { JZ DONE }
$2C/$07/ { SUB AL,7 }
$74/$20/ { JZ MONO }
$BA/$00/$B8/ { MOV DX,0B800H }
$8E/$DA/ { MOV DS,DX }
$BA/$DA/$03/ { MOV DX,03DAH }
$EC/ { TESTLOW: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$75/$FB/ { JNZ TESTLOW }
$FA/ { CLI }
$EC/ { TESTHI: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$74/$FB/ { JZ TESTHI }
$8A/$1D/ { MOV BL,DS:[DI] }
$26/$88/$1C/ { MOV ES:[SI],BL }
$47/ { INC DI }
$46/ { INC SI }
$E2/$EC/ { LOOP GETCHAR }
$2A/$C0/ { SUB AL,AL }
$74/$0E/ { JZ DONE }
$BA/$00/$B0/ { MONO: MOV DX,0B000H }
$8E/$DA/ { MOV DS,DX }
$8A/$1D/ { MONO1: MOV BL,DS:[DI] }
$26/$88/$1C/ { MOV ES:[SI],BL }
$47/ { INC DI }
$46/ { INC SI }
$E2/$F7/ { LOOP MONO1 }
$1F); { DONE: POP DS }
End;
{ ===================================================================== }
{ DISPALL - Display an array of characters and attributes on the CRT. }
{ The array is usually one that has been created using the }
{ GetDisp procedure. }
{ The row and column inputs are relative to zero and are }
{ also relative to the entire screen, not any open window. }
{ }
{ Inputs: }
{ colb : byte; Starting column (0 - 79) }
{ rowb : byte; Starting row (0 - 24) }
{ len : byte; length of array (not including attributes)}
{ fromstrng : charptr; Pointer to array to display }
{ ===================================================================== }
Procedure DispAll(colb,rowb,len : byte; fromstrng : charptr);
Begin
Inline(
$1E/ { PUSH DS }
$8A/$86/rowb/ { MOV AL,rowb[BP] }
$B3/$50/ { MOV BL,80 }
$F6/$E3/ { MUL BL }
$2B/$DB/ { SUB BX,BX }
$8A/$9E/colb/ { MOV BL,colb[BP] }
$03/$C3/ { ADD AX,BX }
$03/$C0/ { ADD AX,AX }
$8B/$F8/ { MOV DI,AX }
$C4/$B6/fromstrng/ { LES SI,fromstrng[BP] }
$8B/$8E/len/ { MOV CX,len[BP] }
$03/$C9/ { ADD CX,CX }
$2B/$C0/ { ADD AX,AX }
$8E/$D8/ { MOV DS,AX }
$A0/$49/$04/ { MOV AL,DS:[0449H] }
$22/$C9/ { AND CL,CL }
$74/$32/ { JZ DONE }
$2C/$07/ { SUB AL,7 }
$74/$20/ { JZ MONO }
$BA/$00/$B8/ { MOV DX,0B800H }
$8E/$DA/ { MOV DS,DX }
$BA/$DA/$03/ { MOV DX,03DAH }
$26/$8A/$1C/ { GETCHAR: MOV BL,ES:[SI] }
$EC/ { TESTLOW: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$75/$FB/ { JNZ TESTLOW }
$FA/ { CLI }
$EC/ { TESTHI: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$74/$FB/ { JZ TESTHI }
$88/$1D/ { MOV DS:[DI],BL }
$47/ { INC DI }
$46/ { INC SI }
$E2/$EC/ { LOOP GETCHAR }
$2A/$C0/ { SUB AL,AL }
$74/$0E/ { JZ DONE }
$BA/$00/$B0/ { MONO: MOV DX,0B000H }
$8E/$DA/ { MOV DS,DX }
$26/$8A/$1C/ { MONO1: MOV BL,ES:[SI] }
$88/$1D/ { MOV DS:[DI],BL }
$47/ { INC DI }
$46/ { INC SI }
$E2/$F7/ { LOOP MONO1 }
$1F); { DONE: POP DS }
End;
{ ===================================================================== }
{ DISPLINE - Display a string of characters on the CRT (with the same }
{ attributes) }
{ The row and column inputs are relative to zero and are }
{ also relative to the entire screen, not any open window. }
{ }
{ Inputs: }
{ colb : byte; Starting column (0 - 79) }
{ rowb : byte; Starting row (0 - 24) }
{ attrib : byte; Line attributes }
{ fromstrng : string[80]; String to display }
{ ===================================================================== }
Procedure DispLine(colb,rowb,attrib : byte; VAR fromstrng : winstr);
Begin
Inline(
$1E/ { PUSH DS }
$8A/$86/rowb/ { MOV AL,rowb[BP] }
$B3/$50/ { MOV BL,80 }
$F6/$E3/ { MUL BL }
$2B/$DB/ { SUB BX,BX }
$8A/$9E/colb/ { MOV BL,colb[BP] }
$03/$C3/ { ADD AX,BX }
$03/$C0/ { ADD AX,AX }
$8B/$F8/ { MOV DI,AX }
$8A/$BE/attrib/ { MOV BH,attrib[BP] }
$C4/$B6/fromstrng/ { LES SI,fromstrng[BP] }
$2B/$C9/ { SUB CX,CX }
$26/$8A/$0C/ { MOV CL,ES:[SI] }
$2B/$C0/ { ADD AX,AX }
$8E/$D8/ { MOV DS,AX }
$A0/$49/$04/ { MOV AL,DS:[0449H] }
$22/$C9/ { AND CL,CL }
$74/$34/ { JZ DONE }
$2C/$07/ { SUB AL,7 }
$74/$21/ { JZ MONO }
$BA/$00/$B8/ { MOV DX,0B800H }
$8E/$DA/ { MOV DS,DX }
$BA/$DA/$03/ { MOV DX,03DAH }
$46/ { GETCHAR: INC SI }
$26/$8A/$1C/ { MOV BL,ES:[SI] }
$EC/ { TESTLOW: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$75/$FB/ { JNZ TESTLOW }
$FA/ { CLI }
$EC/ { TESTHI: IN AL,DX }
$A8/$01/ { TEST AL,1 }
$74/$FB/ { JZ TESTHI }
$89/$1D/ { MOV DS:[DI],BX }
$47/ { INC DI }
$47/ { INC DI }
$E2/$EB/ { LOOP GETCHAR }
$2A/$C0/ { SUB AL,AL }
$74/$0F/ { JZ DONE }
$BA/$00/$B0/ { MONO: MOV DX,0B000H }
$8E/$DA/ { MOV DS,DX }
$46/ { MONO1: INC SI }
$26/$8A/$1C/ { MOV BL,ES:[SI] }
$89/$1D/ { MOV DS:[DI],BX }
$47/ { INC DI }
$47/ { INC DI }
$E2/$F6/ { LOOP MONO1 }
$1F); { DONE: POP DS }
End;
{ ======================================================================== }
{ NAME: Normalize VERSION: 1.0 DATE: 23 January 1986 }
{ AUTHOR: Michael Burton }
{ DESCRIPTION: Normalize coordinates }
{ INPUTS: s,e : byte; start and end coordinates }
{ OUTPUTS: s,e : byte; coordinates with s < e }
{ }
{ ======================================================================== }
Procedure Normalize(VAR s,e: byte);
Var temp: byte;
Begin
If s > e Then
Begin
temp := s;
s := e;
e := temp;
End;
End;
{ ======================================================================== }
{ NAME: Bleep VERSION: 1.0 DATE: 14 January 1986 }
{ AUTHOR: Michael Burton }
{ DESCRIPTION: Produce a bleeping sound times number of times }
{ INPUTS: times : byte; The number of bleeps required }
{ }
{ ======================================================================== }
Procedure Bleep(times : byte);
Var i : byte;
Begin
For i := 1 To times Do
Begin
Nosound;
Sound(880);
Delay(60);
Sound(440);
Delay(60);
Nosound;
End;
End;
{ ======================================================================== }
{ NAME: Set_Cursor VERSION: 1.0 DATE: 27 January 1986 }
{ AUTHOR: }
{ DESCRIPTION: Set the cursor size }
{ INPUTS: The number of cursor lines to display (0 -7, 0-14) }
{ }
{ ======================================================================== }
Procedure Set_Cursor (n: byte);
Type
regrec = Record
ax,bx,cx,dx,bp,si,di,ds,es,flags: integer
End;
Var regpak : regrec;
top, bottom : byte;
Begin
If Mem[$0040:$0049] = 7 Then bottom := 13
Else bottom := 7;
regpak.ax:= $100;
If n <= bottom Then top := bottom - n + 1
Else top := 0;
regpak.cx := top shl 8 or bottom;
Intr($10,regpak)
End;
{ ===================================================================== }
{ INITWINDO - Initialize the window variables }
{ }
{ Use this routine before using MAKEWINDO, REMOVEWINDO or TITLEWINDO }
{ }
{ Inputs: }
{ txtcolor : byte; Starting text color }
{ bkgndclr : byte; Starting background color }
{ ===================================================================== }
Procedure InitWindo(txtcolor,bkgndclr : byte);
Begin
brd[5].ul := chr(08); { Set up circle border constants }
brd[5].ur := chr(08);
brd[5].ll := chr(08);
brd[5].lr := chr(08);
brd[5].hz := chr(08);
brd[5].vtl := chr(08);
brd[5].vtr := chr(08);
brd[6].ul := chr(10); { Set up diamond border constants }
brd[6].ur := chr(10);
brd[6].ll := chr(10);
brd[6].lr := chr(10);
brd[6].hz := chr(10);
brd[6].vtl := chr(10);
brd[6].vtr := chr(10);
textcolor(txtcolor);
textbackground(bkgndclr);
wndo[0].rowb := 0; { Initialize non-window zero }
wndo[0].rowe := 24;
wndo[0].colb := 0;
wndo[0].cole := 79;
wndo[0].attrib := (bkgndclr * 16) + txtcolor;
wndo[0].bordr := noneb;
wndo[0].lastx := Wherex;
wndo[0].lasty := Wherey;
l_i := 0;
End;
{ ===================================================================== }
{ MAKEWINDO - Create a window }
{ }
{ Inputs: }
{ colb : byte; Start column (1 - 80) }
{ rowb : byte; Start row (1 - 25) }
{ cole : byte; End column (1 - 80) }
{ rowe : byte; End row (1 - 25) }
{ tcolor : byte; Text color (0 - 15) }
{ tback : byte; Text background (0 - 7, > 7 for blinking) }
{ bordr : boolean; Border indicator (0 - 9) }
{ ===================================================================== }
Procedure MakeWindo(colb,rowb,cole,rowe,tcolor,tback:byte;bordr:byte);
Var i : byte;
wsize : integer;
pseg : integer;
pofs : integer;
mema : real;
Begin
rowb := rowb - 1; { Set coordinates relative to zero }
rowe := rowe - 1;
colb := colb - 1;
cole := cole - 1;
Normalize(rowb,rowe);
Normalize(colb,cole);
wsize := 2 * ((cole - colb + 1) * (rowe - rowb + 1)); { Total size of area }
{ needed to store display }
If l_i + 1 > maxwin Then
Begin
Writeln('Too many Windows!');
Bleep(4);
End
Else
Begin
If memavail < 0 then mema := 65536.0 + memavail
else mema := memavail;
If (wsize DIV 16 + 1) > mema Then
Begin
Writeln('Not enough Heap space!');
Bleep(4);
End
Else
Begin
wndo[l_i].lastx := Wherex; { Store old cursor coordinates }
wndo[l_i].lasty := Wherey;
l_i := l_i + 1; { Go to next window level }
Textcolor(tcolor);
Textbackground(tback);
wndo[l_i].rowb := rowb; { Store all variables for this window }
wndo[l_i].rowe := rowe;
wndo[l_i].colb := colb;
wndo[l_i].cole := cole;
wndo[l_i].attrib := (tback * 16) + tcolor;
wndo[l_i].bordr := bordr;
GetMem(wndoptr[l_i],wsize); { Get enough heap to store old display }
tmpptr := wndoptr[l_i];
For i := rowb To rowe Do { Store old display one row at a time }
Begin
GetDisp(colb,i,(cole-colb+1),tmpptr);
pseg := Seg(tmpptr^);
pofs := Ofs(tmpptr^);
pofs := pofs + 2 * (cole - colb + 1);
tmpptr := Ptr(pseg,pofs);
End;
wndostr[0] := chr(cole - colb + 1); { Set up String length }
If bordr = noneb Then
Begin
FillChar(wndostr[1],cole-colb+1,' '); { Do no border }
For i := rowb To rowe Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
Window(colb+1,rowb+1,cole+1,rowe+1); { Create actual Turbo window }
End
Else
Begin
wndostr[1] := brd[bordr].ul; { Do border top line }
wndostr[cole-colb+1] := brd[bordr].ur;
FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
DispLine(colb,rowb,wndo[l_i].attrib,wndostr);
wndostr[1] := brd[bordr].vtl; { Do border middle lines }
wndostr[cole-colb+1] := brd[bordr].vtr;
FillChar(wndostr[2],cole-colb-1,' ');
For i := rowb+1 To rowe-1 Do DispLine(colb,i,wndo[l_i].attrib,wndostr);
wndostr[1] := brd[bordr].ll; { Do border bottom line }
wndostr[cole-colb+1] := brd[bordr].lr;
FillChar(wndostr[2],cole-colb-1,brd[bordr].hz);
DispLine(colb,rowe,wndo[l_i].attrib,wndostr);
Window(colb+2,rowb+2,cole,rowe); { Create actual Turbo window }
End;
Gotoxy(1,1);
End;
End;
End;
{ ===================================================================== }
{ REMOVEWINDO - Remove the last window created from the screen. To }
{ get back to the original screen, there must be as many }
{ Removewindos as there are Makewindos. }
{ }
{ Inputs: }
{ None }
{ ===================================================================== }
Procedure RemoveWindo;
Var i : byte;
wsize: integer;
pseg : integer;
pofs : integer;
Begin
If l_i = 0 Then
Begin
Writeln('No Window To Remove!');
Bleep(4);
End
Else
Begin
wsize := wndo[l_i].cole - wndo[l_i].colb + 1;
tmpptr := wndoptr[l_i];
For i := wndo[l_i].rowb To wndo[l_i].rowe Do { Put back old display }
Begin
DispAll(wndo[l_i].colb,i,wsize,tmpptr);
pseg := Seg(tmpptr^);
pofs := Ofs(tmpptr^);
pofs := pofs + 2 * wsize;
tmpptr := Ptr(pseg,pofs);
End;
wsize := 2 * ((wndo[l_i].cole - wndo[l_i].colb + 1) * (wndo[l_i].rowe - wndo[l_i].rowb + 1));
FreeMem(wndoptr[l_i],wsize); { Release heap space }
l_i := l_i - 1; { Go to next lower level }
Textcolor(wndo[l_i].attrib AND $0F); { Set up all for this level }
Textbackground(wndo[l_i].attrib DIV 16);
If wndo[l_i].bordr = noneb Then
Window(wndo[l_i].colb+1,wndo[l_i].rowb+1,wndo[l_i].cole+1,wndo[l_i].rowe+1)
Else
Window(wndo[l_i].colb+2,wndo[l_i].rowb+2,wndo[l_i].cole,wndo[l_i].rowe);
Gotoxy(wndo[l_i].lastx,wndo[l_i].lasty);
End;
End;
{ ===================================================================== }
{ TITLEWINDO - Place a centered title in the top border of a window. }
{ }
{ Inputs: }
{ title : string[80]; The title of the window }
{ ===================================================================== }
Procedure TitleWindo (title: winstr);
Var i : byte;
Begin
i := (((wndo[l_i].cole-wndo[l_i].colb) - length(title)) DIV 2 + 1) + wndo[l_i].colb;
DispLine(i,wndo[l_i].rowb,wndo[l_i].attrib,title);
End;